import { ElMessage, ElMessageBox } from 'element-plus'
export const Message = ElMessage
export const MessageBox = ElMessageBox

/**
 * 给downloadFileBase64函数得base64文件加前缀
 */
const splicingTogether = (filename: string, base64: string) => {
  try {
    const _name = filename.split('.')
    const data = base64.split(',')
    switch (_name[_name?.length - 1]) {
      case 'txt':
        return 'data:text/plain;base64,' + data[1]
      case 'doc':
        return 'data:application/msword;base64,' + data[1]
      case 'docx':
        return (
          'data:application/vnd.openxmlformats-officedocument.wordprocessingml.document;base64,' +
          data[1]
        )
      case 'xls':
        return 'data:application/vnd.ms-excel;base64,' + data[1]
      case 'xlsx':
        return (
          'data:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;base64,' + data[1]
        )
      case 'pdf':
        return 'data:application/pdf;base64,' + data[1]
      case 'pptx':
        return (
          'data:application/vnd.openxmlformats-officedocument.presentationml.presentation;base64,' +
          data[1]
        )
      case 'ppt':
        return 'data:application/vnd.ms-powerpoint;base64,' + data[1]
      case 'png':
        return 'data:image/png;base64,' + data[1]
      case 'jpg':
        return 'data:image/jpeg;base64,' + data[1]
      case 'jpeg':
        return 'data:image/jpeg;base64,' + data[1]
      case 'gif':
        return 'data:image/gif;base64,' + data[1]
      case 'svg':
        return 'data:image/svg+xml;base64,' + data[1]
      case 'ico':
        return 'data:image/x-icon;base64,' + data[1]
      case 'bmp':
        return 'data:image/bmp;base64,' + data[1]
      default:
        return base64
    }
  } catch (error) {
    return base64
  }
}

/**
 * base64 下载
 * @fileName 文件名称
 * @base64 base64文件
 */
export function downloadFileBase64(fileName: string, base64: string) {
  if ('download' in document.createElement('a')) {
    // 非IE下载
    const elink = document.createElement('a')
    elink.download = fileName
    elink.style.display = 'none'
    elink.href = splicingTogether(fileName, base64)
    document.body.appendChild(elink)
    elink.click()
    document.body.removeChild(elink)
  }
}

export const fileCanDownload = async (data: Blob) => {
  if (data.size > 2000) return true
  const txt = await data.text()
  let obj: any = {}
  try {
    obj = JSON.parse(txt)
  } catch (e) {
    console.error(e)
  }
  if (obj.code) {
    console.error(obj.msg || '下载文件失败')
    return false
  }
  return true
}

/**
 * blob 下载
 * @fileName 文件名称
 * @resBlob blob文件
 */
export async function downloadFile(fileName: string, resBlob: Blob) {
  const canDownload = await fileCanDownload(resBlob)
  if (!canDownload) return
  const blob = new Blob([resBlob])
  if ('download' in document.createElement('a')) {
    // 非IE下载
    const elink = document.createElement('a')
    elink.download = fileName
    elink.style.display = 'none'
    elink.href = URL.createObjectURL(blob)
    document.body.appendChild(elink)
    elink.click()
    URL.revokeObjectURL(elink.href) // 释放URL 对象
    document.body.removeChild(elink)
  }
}

function getMidNum(str: any, start: any, len: any) {
  if (start + len > 0) {
    return +str.substr(start < 0 ? 0 : start, start < 0 ? start + len : len)
  } else {
    return 0
  }
}

/**
 * 大数据比较大小,支持千分位数字
 * a<b返回 -1
 * a==b 返回 0
 * a>b 返回 1
 */
export const bigNumCompare = (_a: string | number, _b: string | number) => {
  const a = _a + ''
  const b = _b + ''
  let back = 0
  const max = Math.ceil(Math.max(a.length, b.length) / 15)
  //分成多少段,从左边开始
  for (let i = max; i > 0; i--) {
    const num1 = getMidNum(a, a.length - i * 15, 15)
    const num2 = getMidNum(b, b.length - i * 15, 15)
    //15位数字相减
    const cur = num1 - num2
    if (cur < 0) {
      back = -1
      break
    } else if (cur > 0) {
      back = 1
      break
    }
  }
  return back
}

/**
 * JSON导出excel
 * @params {
 *  data:Array 原数据
 *  FileName:string 导出的文件名,默认为时间戳
 *  titleMapping:Array [{
 *      title:string 列名,
 *      sort:number 排序,
 *      field:string 对应字段
 *    }],
 *  tableName:string 工作表名称
 * }
 */
export const exportExcel = (params: any) => {
  const { data, FileName = Date.now(), titleMapping, tableName = 'Sheet1' } = params
  if (!data) return
  let JSONData: any = data
  let title: any = []
  if (titleMapping?.length) {
    const sortData = titleMapping.sort((a: number, b: number) => a - b)
    JSONData = JSONData.map((ele: any) => {
      const obj: any = {}
      sortData.forEach((item: any) => {
        obj[item.field] = ele[item.field]
      })
      return obj
    })
    title = titleMapping.map((ele: any) => ele.title)
  } else {
    title = Object.keys(data[0])
    JSONData = JSONData.map((ele: any) => {
      const obj: any = {}
      title.forEach((item: any) => {
        obj[item] = ele[item]
      })
      return obj
    })
  }
  const arrData = typeof JSONData != 'object' ? JSON.parse(JSONData) : JSONData
  let excel = '<table>'
  let row = '<tr>'
  if (title) {
    for (const i in title) {
      row += "<th align='center'>" + title[i] + '</th>'
    }
  } else {
    for (const i in arrData[0]) {
      row += "<th align='center'>" + i + '</th>'
    }
  }
  excel += row + '</tr>'
  for (let i = 0; i < arrData.length; i++) {
    let row = '<tr>'
    for (const index in arrData[i]) {
      const value = arrData[i][index] == null ? '' : arrData[i][index]
      row += "<td align='center'>" + value + '</td>'
    }
    excel += row + '</tr>'
  }
  excel += '</table>'
  let excelFile =
    "<html xmlns:o='urn:schemas-microsoft-com:office:office' xmlns:x='urn:schemas-microsoft-com:office:excel' xmlns='http://www.w3.org/TR/REC-html40'>"
  excelFile += '<meta http-equiv="content-type" content="application/vnd.ms-excel; charset=UTF-8">'
  excelFile += '<meta http-equiv="content-type" content="application/vnd.ms-excel'
  excelFile += '; charset=UTF-8">'
  excelFile += '<head>'
  excelFile += '<!--[if gte mso 9]>'
  excelFile += '<xml>'
  excelFile += '<x:ExcelWorkbook>'
  excelFile += '<x:ExcelWorksheets>'
  excelFile += '<x:ExcelWorksheet>'
  excelFile += '<x:Name>'
  excelFile += `{${tableName}}`
  excelFile += '</x:Name>'
  excelFile += '<x:WorksheetOptions>'
  excelFile += '<x:DisplayGridlines/>'
  excelFile += '</x:WorksheetOptions>'
  excelFile += '</x:ExcelWorksheet>'
  excelFile += '</x:ExcelWorksheets>'
  excelFile += '</x:ExcelWorkbook>'
  excelFile += '</xml>'
  excelFile += '<![endif]-->'
  excelFile += '</head>'
  excelFile += '<body>'
  excelFile += excel
  excelFile += '</body>'
  excelFile += '</html>'
  const uri = 'data:application/vnd.ms-excel;charset=utf-8,' + encodeURIComponent(excelFile)
  const link = document.createElement('a')
  link.href = uri
  link.style.visibility = 'hidden'
  link.download = FileName + '.xls'
  document.body.appendChild(link)
  link.click()
  document.body.removeChild(link)
}

/**
 * @description: file文件转base64
 * @param {File} file
 * @return {*} Promise  ==> base64
 */
export const fileToBase64 = (file: File): any => {
  return new Promise((resolve, reject) => {
    const reader: any = new FileReader()
    reader.readAsDataURL(file)
    reader.onload = (res: any) => {
      if (res.explicitOriginalTarget) {
        resolve(res.explicitOriginalTarget.result)
      } else if (res.srcElement?.result) {
        resolve(res.srcElement.result)
      } else if (res.target?.result) {
        resolve(res.target.result)
      } else {
        reject('')
      }
    }
  })
}

function _copy(text: string) {
  const textArea = document.createElement('textarea')
  textArea.value = text
  // 使text area不在viewport，同时设置不可见
  document.body.appendChild(textArea)
  textArea.focus()
  textArea.select()
  new Promise((resolve, reject) => {
    // 执行复制命令并移除文本框
    document.execCommand('copy') ? resolve(null) : reject()
    textArea.remove()
  })
    .then(() => {
      ElMessage.success('复制成功')
    })
    .catch(() => {
      ElMessage.error('复制失败,请手动复制')
    })
}

/**
 * @description: 复制文字到剪贴板
 * @param {string} text
 * @return {*}
 */
export const copyText = (text: string): any => {
  if (navigator.clipboard) {
    navigator.clipboard
      .writeText(text)
      .then(() => {
        ElMessage.success('复制成功')
      })
      .catch(() => {
        _copy(text)
      })
  } else {
    _copy(text)
  }
}
/**
 * @list 原数组
 * @search 匹配的文字
 * @fieldName 被匹配对象字段名
 */
export const fuzzySearch = (list: Array<any>, search: string, fieldName: string) => {
  if (!search) return list
  let data: Array<any> = []
  if (list.length != 0 && search) {
    let str = 'S*' + search + 'S*'
    let reg = new RegExp(str, 'i') //不区分大小写
    list.map((item) => {
      //item是一个对象,name循环这个对象的每一项进行模糊查询
      if (typeof item == 'object') {
        if (reg.test(item[fieldName])) {
          data.push(item)
        }
      } else {
        if (reg.test(item)) {
          data.push(item)
        }
      }
    })
  }
  return data
}

/**
 * @config 上传文件得配置
 * @ config.accept允许的文件类型 ".jpg,.png"
 * @ config.multiple 是否允许上传多个 config.maxLimit不为0 时 config.multiple自动为true
 * @ config.maxSize 最大欲奴上传大小  单位 MB
 * @ config.maxLimit 最多上传个数
 */
export const _uploads = (config: {
  accept?: string
  multiple?: boolean
  maxSize?: number
  maxLimit?: number
  maxList: number
}) => {
  const _config: {
    accept: string
    multiple: boolean
    maxSize: number
    maxLimit: number
    maxList: number
  } = {
    accept: '',
    multiple: false,
    maxSize: 99999,
    maxLimit: 0,
    ...config
  }
  if (_config.maxLimit) _config.multiple = true
  return new Promise((resolve, reject) => {
    const InputFile = document.createElement('input')
    InputFile.type = 'file'
    InputFile.accept = _config.accept //文件类型
    InputFile.multiple = _config.multiple //是否多文件上传
    InputFile.click()
    InputFile.addEventListener('change', (e: any) => {
      const files = e.target?.files
      const ossList = []

      if (files.length > _config.maxLimit && _config.maxList) {
        Message('error', '上传文件数量不能超过 ' + _config.maxLimit + '个!')
        reject()
        return
      }

      for (let i = 0; i < files.length; i++) {
        const ele = files[i]
        if (ele.size / 1024 / 1024 > _config.maxSize) {
          Message('error', '请上传不大于' + _config.maxSize + 'MB的文件')
          new Error('文件太大啦')
          break
        }
        ossList.push(ele)
      }
      resolve(ossList)
    })
  })
}

export const urlToBase64 = async (url: string) => {
  const response = await fetch(url)
  if (!response.ok) {
    return url
  }
  const blob = await response.blob()
  return await new Promise((resolve, reject) => {
    const reader = new FileReader()
    reader.onloadend = () => resolve(reader.result)
    reader.onerror = () => {
      reject('失败')
      Message.error('失败')
    }
    reader.readAsDataURL(blob)
  })
}
